﻿using GylCSharpUtils.Common.Base;
using GylCSharpUtils.Common.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace GylCSharpUtils.GSerializer.Template {
    public class GSTemplate {

        public static readonly BindingFlags GSFieldBindFlag = BindingFlags.Public;
        
        public ulong GSTID { get; private set; }
        public Type iType { get; private set; }
        private string[] fieldTypeList;
        public string[] FieldTypeList { 
            get {
                string[] strings = new string[fieldTypeList.Length];
                Array.Copy(fieldTypeList, strings, fieldTypeList.Length);
                return strings;
            }
            set {
                fieldTypeList = value;
            }
        }
        public ushort FieldNum { get; private set; }
        private GSTFieldInfo[] fieldInfoList;
        public GSTFieldInfo[] FieldInfoList { 
            get {
                var len = fieldInfoList.Length;
                GSTFieldInfo[] ret = new GSTFieldInfo[len];
                Array.Copy(fieldInfoList, ret, len);
                return ret;
            }
            set {
                fieldInfoList = value;
            }
        }
        public string TemplateStr { get; private set; }
        public string TemplateStrShort { get { return ShortStr(); } set { } }
        private string TStrShort;
        private string PreStr, PostStr;

        protected internal GSTemplate(ulong gstid, Type type,List<string> fieldTypeNames, List<GSTFieldInfo> fieldInfos, string templateStr,string preStr, string postStr) {
            GSTID = gstid;
            iType = type;
            FieldTypeList = fieldTypeNames.ToArray();
            FieldNum = (ushort)fieldInfos.Count;
            FieldInfoList = fieldInfos.ToArray();
            TemplateStr = templateStr;
            PreStr = preStr;
            PostStr = postStr;
        }

        internal static GSTemplate CreateGST(Type type, ulong[] gstIdList, GSTFieldInfo[] fieldInfos) {
            if(type == null || gstIdList == null || gstIdList == null || fieldInfos == null) throw new Exception("模板信息不可为空");
            Array.Sort(gstIdList);
            Dictionary<ulong, int> dict = new Dictionary<ulong, int>();
            for(int i = 0; i < gstIdList.Length; i++) dict.Add(gstIdList[i], i);



            return null;

        }


        private string ShortStr() {
            if(TStrShort != null) return TStrShort;
            var len = FieldTypeList.Length;
            bool[] flags = new bool[len];
            ulong[] gstids = new ulong[len];
            // 获取所有字段使用的类型的GSTID
            foreach(var info in FieldInfoList) {
                var index = info.TemplateIndex;
                if(flags[index]) continue;
                if(info.FieldType.Equals(iType)) {
                    gstids[index] = 0;
                } else {
                    gstids[index] = GSTManager.GetGSTID(info.FieldType);
                }
                flags[index] = true;
            }
            // 按顺序构建字符串
            var fieldTypeListStr = ArrayUtils.ToStr(gstids);
            // 组装字符串
            TStrShort = new StringBuilder()
                .Append("{")
                .Append(PreStr)
                .AppendFormat("\"FieldTypeList\":{0}", fieldTypeListStr)
                .Append(PostStr)
                .Append("}")
                .ToString();
            return TStrShort;
        }

        
    }
}
